home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-08-16 | 82.3 KB | 1,033 lines |
- $SET LIST STACK LINEINFO LISTINCL FORMAT $ ERRLIST 00000001
- $SET LEVEL 2 00000002
- PROCEDURE KERMIT (INIT); 01000000
- ARRAY INIT[*]; 01001000
- BEGIN 01002000
- DEFINE 10000000
- % PACKET LENGTH DEFINES 10001000
- MYPAD = 10 # % # OF PAD CHARS (SET EXPERIMENTALLY) 10002000
- , MYTIMOUT= 5 # % SECONDS TO WAIT BEFORE TIMEOUT 10002500
- , MAXPACKET = 96 # % MAXIMUM LENGTH OF A PACKET 10003000
- , MAXDATA = (MAXPACKET - 5) # % MOST DATA IN PACKET 10004000
- , PADPACKETLENGTH = (MAXPACKET + MYPAD) # % MOST WE MIGHT RECEIVE10005000
- , MAXINTEGER = 4"7FFFFFFFFF" # % LARGEST INTEGER ON B6800 10005250
- , RETRYLIMIT = 10 # % NUMBER OF NAK RETRIES BEFORE ABORT 10005500
- ; 10006000
- REAL MARK, SEQ, STATE 11000000
- , YOURMAXBUFF, YOURNPAD, YOURPAD, YOUREOL, YOURQUOTE, YOUR8BIT 11000250
- , YOURREPEAT, YOURTIMOUT 11000500
- ; 11000750
- BOOLEAN DEBUGGING, RSLT, AUTOING; 11001000
- FILE RMT (KIND=REMOTE,FRAMESIZE=8, MYUSE=IO 11002000
- ,MAXRECSIZE=PADPACKETLENGTH,MINRECSIZE=1 11003000
- ) 11004000
- , FYLE (KIND=DISK, FRAMESIZE=8) 11004500
- , DEBUGFILE (KIND=PRINTER, FRAMESIZE=8) 11005000
- ; 11006000
- ARRAY CTLCHARS [0:7]; % DYNAMIC TRUTHSET: CHARS NEEDING CTL QUOTING 11700000
- DEFINE B = BOOLEAN # 120010020.01.002
- , R = REAL # 120010040.01.002
- , P = POINTER # 120010060.01.002
- , INT = INTEGER # 120010080.01.002
- , SIGNF = [46:1] # 1200101001.188.000
- , LISTOF2(L1,L2) = L1,L2 #1200101201.188.004
- , LISTOF3(L1,L2,L3) = L1,L2,L3 #1200101401.188.004
- , LISTOF4(L1,L2,L3,L4) = L1,L2,L3,L4 #1200101601.188.004
- , LISTOF5(L1,L2,L3,L4,L5) = L1,L2,L3,L4,L5 #1200101801.188.004
- , LISTOF6(L1,L2,L3,L4,L5,L6) = L1,L2,L3,L4,L5,L6 #1200102001.188.004
- , LISTOF7(L1,L2,L3,L4,L5,L6,L7) = L1,L2,L3,L4,L5,L6,L7 #1200102201.188.004
- , LISTOF8(L1,L2,L3,L4,L5,L6,L7,L8) = L1,L2,L3,L4,L5,L6,L7,L8 #1200102401.188.004
- , LISTOF9(L1,L2,L3,L4,L5,L6,L7,L8,L9)= L1,L2,L3,L4,L5,L6,L7,L8,L9 #1200102601.188.004
- , FILEEOF = [9:1] # 1200102801.188.000
- , FILEBRK = [13:1] # 1200103001.188.000
- , ALLONES = REAL(NOT FALSE) # 1200103201.188.007
- , ORD(X) = REAL(X,1) # %ORDINAL OF CHARACTER 120010340.01.002
- , CHAR(X) = ((X).[7:48]) FOR 1 # % CHARACTER VALUE OF INTEGER 12001036
- % OR ALPHA EXPRESSION 120010380.01.002
- , ERRORCODEF = [47:47] # % FOR PUTTING A REAL VALUE INTO A BOOLEAN12001040
- , POP(X) = X:=*.ERRORCODEF # 12001042
- , POPPED(X) = (X).ERRORCODEF # 12001044
- , PUSHIN(X) = (X) ERRORCODEF # 12001046
- , BOOLINTOBOOL (B1,B2) = B2 & PUSHIN(B1) # 12001048
- , REALINTOBOOL (R,B) = BOOLINTOBOOL (BOOLEAN(R),B)# 12001050
- , LINKF = [19:20] # % STANDARD LINK FIELD 12001052
- , SZ(X) = 0:X-1 # % FOR ARRAY DECLARATION 12001054
- ; 12001056
- PROCEDURE DUMPARRAY (WIRETAP,L,SOU,TYPE,INASCII); 12002010
- VALUE L,SOU,TYPE,INASCII ; 12002020
- FILE WIRETAP ; 12002030
- REAL L, TYPE ; 12002040
- POINTER SOU ; 12002050
- BOOLEAN INASCII ; 12002060
- COMMENT: PRODUCES A HEX AND ALPHANUMERIC DUMP OF THE CONTENTS OF AN 12002080
- ARRAY TO A PRINTER FILE. 12002090
- IT WILL LOOK SOMETHING LIKE: 12002100
- 12002110
- -TYPE- C O N T E N T S O F T H E A R 12002120
- C1D6D5E3C5D5 E3E240D6C640 E3C8C540C1D9 12002130
- 12002140
- R A Y 12002150
- D9C1E8 12002160
- 12002170
- PARAMETERS: 12002180
- WIRETAP: IS A PRINTER FILE ONTO WHICH THE DUMP IS MADE. 12002190
- L: IS THE LENGTH (NUMBER OF CHARACTERS TO DUMP). 12002200
- SOU: IS THE SOURCE POINTER -- POINTS TO THE FIRST CHARACTER 12002210
- TO DUMP. 12002220
- TYPE: SHOULD CONTAIN A SIX CHARACTER IDENTIFICATION MESSAGE.12002230
- IT IS PRINTED ON THE DUMP TO THE LEFT OF THE ARRAY 12002240
- CONTENTS. 12002250
- INASCII: IF TRUE, THE ARRAY CONTENTS ARE CONSIDERED TO BE IN12002260
- ASCII AND WILL BE TRANSLATED TO EBCDIC FOR THE 12002270
- ALPHA PART OF THE DUMP. 12002280
- ; 12002290
- BEGIN 1200232001.188.001
- ARRAY A1[0:9], A2[0:18], ED[0:20] %EDITED BY PICTURE 12002330
- ; 1200234001.188.001
- BOOLEAN BOO; 1200235001.188.001
- REAL RM % REMAINING 1200236001.188.001
- , CTS % CHARACTERS TO SHOW (ON THIS LINE) 1200237001.188.001
- , BL % BLANKS TO PUT AT END 1200238001.188.001
- , PLL % PRINT LINE LENGTH 12002390
- ; 1200240001.188.001
- POINTER PA2 1200241001.188.001
- , SLO % SOURCE LEFT OFF 1200242001.188.001
- ; 1200243001.188.001
- PICTURE ALPHALINE( AXAXAXAXAXAXX AXAXAXAXAXAXX AXAXAXAXAXAXX 1200244001.188.001
- AXAXAXAXAXAXX AXAXAXAXAXAXX AXAXAXAXAXAXX 1200245001.188.001
- AXAXAXAXAXAXX AXAXAXAXAXAXX AXAXAXAXAXAXX 1200246001.188.001
- ) 1200247001.188.001
- , HEXLINE ( A(12)X A(12)X A(12)X 1200248001.188.001
- A(12)X A(12)X A(12)X 1200249001.188.001
- A(12)X A(12)X A(12)X 1200250001.188.001
- ) 1200251001.188.001
- ; 1200252001.188.001
- 1200253001.188.001
- PA2:=P(A2); 1200254001.188.001
- SLO:=SOU; 1200255001.188.001
- RM :=L; 1200256001.188.001
- REPLACE P(ED) BY TYPE FOR 6, " " FOR 20 WORDS; 1200257001.188.001
- 1200258001.188.001
- DO 1200259001.188.001
- BEGIN 1200260001.188.001
- BL:=54-(CTS:=MIN(RM,54)); 1200261001.188.001
- IF INASCII THEN % WHAT WE ARE WRITING IS IN ASCII 1200262001.188.001
- BEGIN 1200263001.188.001
- REPLACE P(A1,7) BY SLO:SLO FOR CTS; 1200264001.188.001
- REPLACE PA2 BY P(A1,7) FOR CTS WITH ASCIITOEBCDIC 1200265001.188.001
- , " " FOR BL 1200266001.188.001
- END 1200267001.188.001
- ELSE 1200268001.188.001
- BEGIN 1200269001.188.001
- REPLACE P(A1) BY SLO:SLO FOR CTS; 1200270001.188.001
- REPLACE PA2 BY P(A1) FOR CTS, " " FOR BL 1200271001.188.001
- END; 1200272001.188.001
- REPLACE P(ED[1])+1 BY PA2 WITH ALPHALINE; 1200273001.188.001
- PLL := IF WIRETAP.FRAMESIZE = 48 THEN 21 12002740
- ELSE 126; 12002750
- BOO:=WRITE(WIRETAP,PLL,ED); 12002760
- 1200277001.188.001
- REPLACE PA2 BY P(A1,4) FOR CTS*2 WITH HEXTOEBCDIC 1200278001.188.001
- , " " FOR BL*2; 1200279001.188.001
- REPLACE P(ED) BY " " FOR 7 1200280001.188.001
- , PA2 WITH HEXLINE; 1200281001.188.001
- BOO:=WRITE(WIRETAP[SPACE 2],PLL,ED); 12002820
- 1200283001.188.001
- REPLACE P(ED[1]) BY " " FOR 20 WORDS; 1200284001.188.001
- END 12002850
- UNTIL RM:=*-CTS = 0 12002860
- END D E B U G W R I T E ; 12002870
- DEFINE DEBUGARRAY (L,PTR,TYPE,INASCII)= 12003000
- IF DEBUGGING THEN DUMPARRAY(DEBUGFILE,L,PTR,TYPE,INASCII) # 12004000
- ; 12005000
- DEFINE 13000000
- % BASIC KERMIT TRANSFORMATION FUNCTIONS: 13001000
- UNCHAR(X) = (ORD(X) -32) # % FROM PRINTABLE TO BINARY 13002000
- , KERCHAR(X) = CHAR(X+32) # % BINARY TO PRINTABLE 13003000
- , CTL(X) = (REAL(NOT(B(X)EQV B(64))).[7:8]) # %CTL TO PRINTABLE--13004000
- , CTLCHAR(X) = CHAR(CTL(X)) # %OR VISE VERSA 13004500
- ; 13005000
- DEFINE AUTORCV = 48"BF" # % NDL -- AUTOMATICALLY RCV "D" PACKETS 18001000
- , ASCIICRVAL = 13 # % DECIMAL VALUE OF AN ASCII CR 18002000
- , ASCIILFVAL = 10 # % DECIMAL VALUE OF AN ASCII LF (OR NL) 18003000
- 18004000
- , CAND (X,Y) = IF X THEN Y ELSE FALSE # 18005000
- , COR (X,Y) = IF X THEN TRUE ELSE Y # 18006000
- ; 18007000
- DEFINE % PACKET TYPE CODES (FOR INTERNAL COMMUNICATIONS) 19000000
- % DATA PACKETS (EVEN) 19001000
- DATA_TYPE = 0 # 19002000
- , AUTO_TYPE = 2 # 19003000
- % CONTROL PACKETS (ODD) 19004000
- , ACK_TYPE = 1 # 19005000
- , NAK_TYPE = 3 # 19006000
- , S_TYPE = 5 # % SEND PACKET 19007000
- , F_TYPE = 7 # % FILE SPEC PACKET 19008000
- , Z_TYPE = 9 # % EOF PACKET 19009000
- , B_TYPE = 11 # % BREAK PACKET 19010000
- , ERR_TYPE = -1 # % BAD NEWS, "E" PACKET, IO ERROR, OR FAULT 19011000
- ; 19012000
- REAL PROCEDURE ACCUM_CHECKSUM (CH,L); 20000000
- VALUE CH,L; 20001000
- POINTER CH; % FIRST CHAR TO CHECKSUM 20002000
- REAL L; % # OF CHARS TO CHECKSUM 20003000
- BEGIN 20004000
- REAL A; % ACCUMULATOR 20005000
- 20006000
- DO 20007000
- BEGIN 20008000
- A:=*+ ORD(CH); 20009000
- CH:=*+ 1 20010000
- END 20011000
- UNTIL L:=*- 1 = 0; 20012000
- A:=A.[7:8]; 20013000
- ACCUM_CHECKSUM:=(A + A.[7:2]).[5:6]; 20014000
- END A C C U M C H E C K S U M ; 20015000
- ASCII ARRAY PKT[0:PADPACKETLENGTH]; % PACKET GOES HERE 22000000
- REAL PKL; % LENGTH OF PACKET 22001000
- DEFINE % PACKET CONTROL CHARACTERS 22002000
- MARK_CHAR = PKT[0] # 22003000
- , COUNT_CHAR = PKT[1] # % # CHARS IN PACKET 22004000
- , SEQ_CHAR = PKT[2] # % MESSAGE # 22005000
- , TYPE_CHAR = PKT[3] # % TYPE OF PACKET 22006000
- , FIRST_DATA = PKT[4] # % FIRST CHAR OF DATA 22007000
- ; 22008000
- DEFINE % VALUES RETURNED FROM PGET 22009000
- % PACKET IS OK: 22010000
- PG_OK = 0 # % PACKET IS OK 22011000
- % IO ERRORS (NO PACKET RECEIVED): 22012000
- , PG_TIMEOUT = 1 # % TIMEOUT 22013000
- , PG_EOF = 2 # % EOF 22014000
- , PG_IOERR = 3 # % IO ERROR ON RECV 22015000
- % BADLY FORMED PACKET 22016000
- , PG_NOMARK = 4 # % NO MARK (SOH) CHARACTER FOUND 22017000
- , PG_SHORT = 5 # % PACKET SHORTER THAN LENGTH CHAR SEZ 22018000
- , PG_CKSM = 6 # % CHECKSUM ERROR 22019000
- % PACKET OUT OF SEQUENCE 22020000
- , PG_SQHIGH = 7 # % SEQ IN PACKET = SEQ + 1 22021000
- , PG_SQLOW = 8 # % SEQ IN PACKET = SEQ - 1 22022000
- , PG_SEQERR = 9 # % WAY OUT OF SEQUENCE 22023000
- ; 22024000
- REAL PROCEDURE PGET(TL); 22025000
- VALUE TL; 22025250
- BOOLEAN TL; % TIME LIMIT -- IF TRUE ENFORCE TIME LIMIT ON RCV: 22025500
- COMMENT: THIS IS THE PRIMITIVE PACKET GET ROUTINE. IT READS THE 22026000
- DATACOM FILE TO TRY AND GET A PACKET. IT MAY TIMEOUT, 22027000
- GET AN IO ERROR OR RECEIVE SOMETHING. IF IT GETS SOMETHING 22028000
- IT LOOKS FOR A MARK (SOH) WHICH SIGNALS A KERMIT PACKET. 22029000
- IF A MARK IS FOUND, THE PACKET IS TRANSLATED TO ASCII, ALIGNED22030000
- TO THE PREDEFINED LOCATIONS OF THE PACKET CONTROL CHARACTERS 22031000
- AND VERIFIED AS A GOOD PACKET. A ZERO IS RETURNED IF A VALID 22032000
- PACKET HAS BEEN RECEIVED. A NON-ZERO VALUE SIGNALS SOME KIND 22033000
- OF ABNORMAL CONDITION. THE POSSIBLE VALUES RETURNED ARE 22034000
- DEFINED ABOVE. IT IS UP TO THE CALLER TO TAKE THE APPROPRIATE22035000
- ACTION WHEN AN ABNORMALL CONDITION OCCURS. 22036000
- 22037000
- IF A PACKET IS RECEIVED FROM THE AUTO RECEIVE HANDLER IN NDL 22038000
- (NDL HAS VERIFIED THE PACKET, ACKED IT, AND HANDLED CONTROL 22039000
- CHARACTER QUOTING) THE PACKET WILL BE PRECEDED BY 48"BF". 22040000
- THIS AUTORCV CODE IS PLACED IN MARK_CHAR WITH THE PACKET 22041000
- CONTENTS (CONVERTED TO ASCII) IMMEDIATELY FOLLOWING. 22042000
- 22043000
- PKL IS SET TO THE LENGTH OF THE DATA PORTION OF THE PACKET. 22044000
- ; 22045000
- BEGIN 22046000
- REAL S; 22047000
- POINTER PP; 22048000
- 22049000
- IF TL THEN RMT.TIMELIMIT:= YOURTIMOUT; % ENFORCE TIME LIMIT? 22049500
- IF RSLT:=READ (RMT,PADPACKETLENGTH,PKT) THEN 22050000
- BEGIN 22051000
- IF DEBUGGING THEN 22052000
- WRITE (DEBUGFILE,<8"RECV ERR: ",H12>,REAL(RSLT)); 22053000
- PGET:= 22054000
- IF RSLT.[15:1] THEN PG_TIMEOUT 22055000
- ELSE 22056000
- IF RSLT.[9:1] THEN PG_EOF 22057000
- ELSE PG_IOERR 22058000
- END 22059000
- ELSE % HANDLE GOOD RECIVE HERE--IS IT A GOOD PKT? 22060000
- BEGIN 22061000
- PKL:= RMT.CURRENTRECORD; 22062000
- DEBUGARRAY (PKL,PKT,8"> IN >",COR(AUTOING,PKT=AUTORCV)); 22063000
- IF PKT= AUTORCV THEN 22064000
- BEGIN 22064500
- PKL:=*-1; % DON'T COUNT AUTORCV CHAR 22065000
- AUTOING:= TRUE % MAKE A NOTE THAT WE'RE AUTO RECEIVING 22065500
- END 22067500
- ELSE % NOT AUTO "D" PKT FROM NDL 22069000
- BEGIN 22070000
- SCAN PP:PKT FOR PKL:PKL UNTIL = MARK; 22071000
- IF PKL< 5 THEN % NO MARK OR TOO SHORT TO BE VALID PACKET 22072000
- PGET:= PG_NOMARK 22073000
- ELSE 22074000
- BEGIN 22075000
- IF AUTOING THEN 22076100
- BEGIN 22076200
- % JUST GOT OUT OF NDL AUTO RECV. THERE IS NO 22076225
- % PADDING BEFORE THE PACKET, AND THE SEQ CHAR HAS 22076250
- % BEEN VERIFIED BY NDL. THE COUNT, SEQ, AND TYPE 22076275
- % CHARACTERS ARE IN ASCII, BUT THE REST ARE IN 22076280
- % EBCDIC 22076290
- AUTOING:= FALSE; 22076300
- REPLACE MARK_CHAR BY PP:PP FOR 4; % MK,CNT,SEQ,TYPE 22076320
- REPLACE FIRST_DATA BY PP FOR PKL-4 22076325
- WITH EBCDICTOASCII; 22076350
- SEQ:= UNCHAR(SEQ_CHAR) % RE-SYNC 22076400
- END 22076500
- ELSE REPLACE MARK_CHAR BY PP FOR PKL WITH EBCDICTOASCII;22076750
- IF PKL < PKL:=UNCHAR(COUNT_CHAR) THEN 22077000
- PGET:= PG_SHORT 22078000
- ELSE 22079000
- IF ACCUM_CHECKSUM (COUNT_CHAR,PKL) NEQ 22080000
- UNCHAR((COUNT_CHAR)+PKL) 22081000
- THEN PGET:= PG_CKSM 22082000
- ELSE % CHECKSUM OK 22083000
- BEGIN 22084000
- PKL:=* -3; % JUST COUNT OF DATA BYTES 22085000
- IF S:= UNCHAR(SEQ_CHAR) - SEQ.[5:6] NEQ 0 22086000
- THEN % OUT OF SEQUENCE 22087000
- PGET:= 22088000
- IF S = 1 THEN PG_SQHIGH 22089000
- ELSE IF S = -1 THEN PG_SQLOW 22090000
- ELSE PG_SEQERR 22091000
- ELSE % GOOD PACKET 22091250
- IF TYPE_CHAR = 7"Y" THEN % ACK PACKET 22091500
- SEQ:= *+1 22091750
- END END END END; 22092000
- 22093000
- RMT.TIMELIMIT:= 0 22094000
- END P G E T ; 22095000
- EBCDIC ARRAY OPKT[0:MAXPACKET]; % LENGTH MAY CHANGE IF PADDING REQ'D 24000000
- BOOLEAN PROCEDURE PPUT (PTYPE,DATAL); 24001000
- COMMENT: PRIMITIVE PUT ROUTINE: 24002000
- FORMATS AND SENDS A PACKET OF THE TYPE ENCODED IN PTYPE. THE 24003000
- TYPE, SEQ AND COUNT FIELDS WILL BE SET TO PROPER VALUES. DATAL 24004000
- BYTES OF DATA (IN ASCII) ARE ASSUMED TO BE PRESENT STARTING AT 24005000
- FIRST_DATA. NO QUOTING IS DONE BY PPUT, AND THUS MUST BE DONE 24006000
- BEFORE CALLING PPUT. PPUT WILL CALCULATE A CHECKSUM AND INSERT 24007000
- IT INTO THE PACKET. THE PACKET IS THEN SENT TO THE REMOTE 24008000
- COMPUTER. 24009000
- 24010000
- THE STATUS WORD FROM THE WRITE TO THE REMOTE COMPUTER IS 24011000
- RETURNED. THE NORMAL VALUE RETURNED IS THUS FALSE, BUT WILL 24012000
- BE TRUE IN THE CASE OF AN IO ERROR. 24013000
- ; 24014000
- VALUE PTYPE,DATAL; 24015000
- REAL PTYPE; % CODE FOR TYPE OF PACKET TO SEND 24016000
- REAL DATAL; % # OF CHARS TO SEND--THEY START AT FIRST_DATA 24017000
- BEGIN 24018000
- POINTER CKSM; % POINTS TO LOCATION FOR CHECKSUM BYTE 24019000
- BOOLEAN RSLT; 24020000
- 24021000
- CKSM:= OPKT; 24022000
- THRU YOURNPAD DO REPLACE CKSM:CKSM BY CHAR(YOURPAD); 24023000
- REPLACE CKSM:OPKT BY CHAR(MARK), KERCHAR(DATAL+3) 24024000
- ,KERCHAR(SEQ.[5:6]); 24025000
- ; 24026000
- CASE PTYPE OF 24027000
- BEGIN 24028000
- (DATA_TYPE) : REPLACE CKSM:CKSM BY 7"D"; 24029000
- (ACK_TYPE) : REPLACE CKSM:CKSM BY 7"Y"; 24030000
- (NAK_TYPE) : REPLACE CKSM:CKSM BY 7"N"; 24031000
- (S_TYPE) : REPLACE CKSM:CKSM BY 7"S"; 24032000
- (F_TYPE) : REPLACE CKSM:CKSM BY 7"F"; 24033000
- (Z_TYPE) : REPLACE CKSM:CKSM BY 7"Z"; 24034000
- (B_TYPE) : REPLACE CKSM:CKSM BY 7"B"; 24035000
- ELSE : REPLACE CKSM:CKSM BY 7"E"; 24036000
- PTYPE:= ERR_TYPE 24037000
- END; 24038000
- REPLACE CKSM:CKSM BY FIRST_DATA FOR DATAL; 24039000
- 24040000
- REPLACE CKSM BY KERCHAR(ACCUM_CHECKSUM(OPKT[1],DATAL+3)); 24041000
- IF CKSM = 7" " THEN % THIS IS TROUBLESOME TO KERMIT ON THE ALTOS 24042000
- BEGIN 24043000
- REPLACE CKSM:=*+1 BY 7"X"; % MAKE IT SEE THE CHECKSUM 24044000
- DATAL:=*+1 % AND BE SURE THE EXTRA CHAR IS SENT 24045000
- END; 24046000
- 24047000
- REPLACE CKSM+1 BY CHAR(YOUREOL); 24048000
- 24049000
- REPLACE OPKT BY OPKT FOR DATAL:=*+6 WITH ASCIITOEBCDIC; 24050000
- 24051000
- DEBUGARRAY (DATAL,OPKT,8"< OUT<",FALSE); 24052000
- WHILE RMT.CENSUS > 0 DO % FLUSH EXTRA MSG 24053000
- RSLT:= READ(RMT,0,PKT); 24054000
- IF NOT RSLT THEN 24055000
- IF NOT RSLT:= WRITE(RMT[STOP],DATAL,OPKT) THEN 24055250
- IF PTYPE = ACK_TYPE THEN SEQ:=*+1; 24055500
- PPUT:= IF RSLT THEN RSLT 24056000
- ELSE IF PTYPE=ERR_TYPE THEN TRUE % REPORT TYPE ERROR 24057000
- ELSE FALSE % OR OK 24058000
- END P P U T ; 24059000
- % SEND AN ERROR MESSAGE TO ABORT OTHER END WITH THIS DEFINE 25000000
- POINTER PERREND; % POINT TO END OF ERROR MESSAGE 25001000
- 25002000
- DEFINE ERROUT(MSG) = % NOTE: MSG IS AN ASCII STRING 25003000
- BEGIN 25004000
- REPLACE PERREND:FIRST_DATA BY MSG; 25005000
- PPUT (ERR_TYPE,DELTA(FIRST_DATA,PERREND)) 25006000
- END # 25007000
- ; 25008000
- 25009000
- 25010000
- 25011000
- 25012000
- REAL PROCEDURE GETPACKET(TL); 30000000
- VALUE TL; 30000250
- BOOLEAN TL; % TIMELIMIT -- TRUE IF A TIMELIMIT 30000500
- COMMENT: 30001000
- THE PURPOSE OF GETPACKET IS TO RETRIEVE THE NEXT VALID PACKET 30002000
- FROM THE REMOTE COMPUTER. GETPACKET WILL NAK IMPROPERLY 30003000
- FORMED PACKETS AND WILL NAK IN THE CASE OF A TIMEOUT. IF TOO 30004000
- MANY NAKS ARE SENT (AS DEFINED BY RETRYLIMIT), GETPACKET WILL 30005000
- ACT AS IF IT HAD JUST RECEIVED AN ERROR (ABORT) PACKET. AN 30006000
- ERROR PACKET WILL ALSO BE REPORTED IN THE CASE OF AN IO ERROR 30007000
- ON THE READ OF THE REMOTE FILE. 30008000
- 30009000
- GETPACKET HANDLES CONTROL QUOTING. ANY CONTROL CHARACTERS IN 30010000
- THE PACKET WHICH WERE QUOTED FOR TRANSFER THROUGH THE DATACOM 30011000
- LINK WILL BE RESTORED. THE PACKET TYPE WILL BE CONVERTED TO 30012000
- THE PACKET TYPE CODE AND RETURNED BY THE GETPACKET PROCEDURE. 30013000
- THE DATA CONTAINED IN THE PACKET MAY BE ACCESSED STARTING AT 30014000
- FIRST_DATA. THE DATA FROM AN AUTO_TYPE PACKET WILL START AT 30015000
- COUNT_CHAR. THE COUNT OF NUMBER OF BYTES OF DATA WILL BE 30016000
- FOUND IN PKL. 30017000
- ; 30018000
- BEGIN 30019000
- REAL E % ERROR CODE RETURNED FROM PGET 30020000
- , RETRY % COUNTDOWN OF RETIES LEFT BEFORE ABORT 30021000
- ; 30022000
- DEFINE DONE (RETURNV) = 30023000
- BEGIN 30024000
- E:= 0; % GET OUT OF THE NAK LOOP 30025000
- GETPACKET:= RETURNV 30026000
- END # 30027000
- , ACK = 30028000
- BEGIN 30028500
- IF PPUT(ACK_TYPE,0) THEN DONE(ERR_TYPE) 30029000
- END # 30030000
- , NAK = 30032000
- BEGIN 30033000
- IF DECREMENTRETRY THEN % TOO MANY RETRIES 30034000
- DONE(ERR_TYPE) 30035000
- ELSE 30036000
- IF PPUT(NAK_TYPE,0) THEN 30037000
- DONE(ERR_TYPE) % UNSUCCESSFUL XMIT 30038000
- %ELSE LOOP BACK FOR ANOTHER TRY 30039000
- END # 30040000
- ; 30041000
- DEFINE % ASCII CHARACTER HEX EQUIVALENTS (CASE WON'T TAKE 7"X") 30042000
- ASC_CHAR_B = 4"42" # 30043000
- , ASC_CHAR_D = 4"44" # 30044000
- , ASC_CHAR_F = 4"46" # 30045000
- , ASC_CHAR_S = 4"53" # 30046000
- , ASC_CHAR_Z = 4"5A" # 30047000
- ; 30048000
- BOOLEAN PROCEDURE DECREMENTRETRY; 30049000
- BEGIN 30050000
- POINTER P1; 30051000
- IF RETRY:=*-1 < 0 THEN 30052000
- BEGIN 30053000
- ERROUT (7"TOO MANY UNSUCCESSFUL ATTEMPTS TO RECEIVE"); 30054000
- DECREMENTRETRY:= TRUE; 30056000
- END 30057000
- END D E C R E M E N T R E T R Y ; 30058000
- PROCEDURE UNQUOTE; 30059000
- BEGIN 30060000
- POINTER P1,P2; 30061000
- REAL L; 30062000
- 30063000
- L:= PKL; 30064000
- P1:= P2:= FIRST_DATA; 30065000
- 30066000
- WHILE L>0 DO 30067000
- BEGIN 30068000
- REPLACE P2:P2 BY P1:P1 FOR L:L UNTIL = YOURQUOTE; 30069000
- IF L>0 THEN % FOUND A QUOTE 30070000
- IF L=1 THEN % SHOULD NEVER BE 30071000
- BEGIN 30072000
- REPLACE P2:P2 BY P1:P1 FOR 1; 30073000
- L:=*-1 30074000
- END 30075000
- ELSE 30076000
- BEGIN 30077000
- PKL:=*-1; % PACKET WILL BE SHORTER--NO MORE QUOTE 30078000
- IF P1:=*+1 = CHAR(YOURQUOTE) THEN % QUOTE QUOTE % 30079000
- REPLACE P2:P2 BY YOURQUOTE % = QUOTE % 30080000
- ELSE REPLACE P2:P2 BY CTLCHAR(ORD(P1)); 30081000
- P1:=*+1; % POINT PAST QUOTED CHAR 30082000
- L:=*-2 30083000
- END END 30084000
- END U N Q U O T E ; 30085000
- % GETPACKET STATEMENTS: 30086000
- 30087000
- RETRY:= RETRYLIMIT; 30088000
- 30089000
- DO 30090000
- IF E:=PGET(TL) = 0 THEN % GOT A GOOD PACKET 30091000
- IF MARK_CHAR = AUTORCV THEN % ALREADY NAKED AND DEQUOTED 30092000
- GETPACKET:= AUTO_TYPE % BY THE NDL 30093000
- ELSE % NORMAL PACKET-- WHAT DO WE DO WITH THIS KIND? 30094000
- CASE ORD(TYPE_CHAR) OF 30095000
- BEGIN 30096000
- (ASC_CHAR_D) : UNQUOTE; 30097000
- (ASC_CHAR_S) : GETPACKET:= S_TYPE; 30098000
- (ASC_CHAR_F) : UNQUOTE; 30099000
- GETPACKET:= F_TYPE; 30100000
- (ASC_CHAR_Z) : ACK; 30101000
- GETPACKET:= Z_TYPE; 30102000
- (ASC_CHAR_B) : ACK; 30103000
- GETPACKET:= B_TYPE; 30104000
- ELSE: ACK; 30105000
- GETPACKET:= ERR_TYPE 30106000
- END CASE 30107000
- ELSE % BAD PACKET OR NO PACKET AT ALL RECEIVED 30108000
- CASE E-1 OF % WHAT KIND OF ERROR? 30109000
- BEGIN 30110000
- NAK; % TIMEOUT 30111000
- DONE(ERR_TYPE); % EOF 30112000
- DONE(ERR_TYPE); % OTHER IO ERROR 30113000
- IF DECREMENTRETRY THEN DONE(ERR_TYPE); % NO MARK 30114000
- NAK; % SHORT 30115000
- NAK; % BAD CHECKSUM 30116000
- NAK; % WE MISSED A PACKET 30117000
- BEGIN % IT MISSED OUR ACK-- TRY ACKING AGAIN 30118000
- SEQ:=*-1; 30119000
- ACK 30120000
- END; 30121000
- NAK; % BAD SEQ 30122000
- END 30123000
- UNTIL E=0; 30124000
- END G E T P A C K E T ; 30125000
- BOOLEAN PROCEDURE PUTPACKET(PTYPE, DATAL); 35000000
- COMMENT: 35001000
- PUTPACKET ADDS ACKNOWLEDGEMENT TO THE SERVICES PROVIDED BY 35002000
- PPUT. PUTPACKET WILL SEND THE PACKET REPEATEDLY UNTIL EITHER 35003000
- AN ACK PACKET IS RECEIVED, AN IO ERROR OCCURS OR UNTIL THE 35004000
- NUMBER OF RETRIES ATTEMPTED EQUAL THE VALUE IN RETRYLIMIT. 35005000
- IF THE PACKET IS SUCCESSFULLY SENT AND ACKNOWLEDGED, PUTPACKET 35006000
- RETURNS A VALUE OF FALSE. IF PUTPACKET FAILS IN ITS MISSION 35007000
- IT RETURNS A TRUE VALUE AFTER ATTEMPTING TO NOTIFY THE REMOTE 35008000
- COMPUTER THAT THIS PROGRA IS NOW ABORTING. 35009000
- 35010000
- THE PARAMETERS TO PUTPACKET ARE THE SAME AS THOSE TO PPUT, AND 35011000
- THE DATA IS NOT MODIFIED, MOVED, OR OTHERWISE CHANGED BEFORE 35012000
- BEING SENT ON TO PPUT. 35013000
- ; 35014000
- VALUE PTYPE, DATAL; 35015000
- REAL PTYPE % CODE FOR TYPE OF PACKET BEING SENT 35016000
- , DATAL % NUMBER OF BYTES TO SEND 35017000
- ; 35018000
- BEGIN 35019000
- REAL RETRY, GETCODE; 35020000
- BOOLEAN RSLT; 35021000
- 35022000
- PROCEDURE SENDFAILURENOTICE; 35023000
- BEGIN 35024000
- ERROUT (7"TOO MANY FAILED ATTEMPTS TO SEND A PACKET"); 35026000
- PUTPACKET:= TRUE % LET CALLER KNOW OF OUR FAILURE 35029000
- END; 35030000
- DEFINE ABORT = % WHEN THINGS ARE TOO DISMAL 35031000
- BEGIN 35032000
- RETRY:= 0; 35033000
- PUTPACKET:= TRUE; 35034000
- PPUT(ERR_TYPE,0); % ATTEMPT TO LET REMOTE KNOW 35035000
- END # 35036000
- , TRYAGAIN = % GOT NAK OR EQUIVALENT 35037000
- BEGIN 35038000
- IF RETRY:=*-1 = 0 THEN SENDFAILURENOTICE 35039000
- END # 35040000
- ; 35041000
- 35042000
- RETRY:= RETRYLIMIT; 35043000
- WHILE RETRY > 0 DO 35044000
- 35045000
- IF RSLT:= PPUT(PTYPE,DATAL) THEN % IO ERROR--FAILURE 35046000
- BEGIN 35047000
- RETRY:= 0; % LEAVE LOOP 35048000
- PUTPACKET:= RSLT; % RETURN NOTICE OF OUR FAILURE 35049000
- PPUT (ERR_TYPE,0); % MAKE A DOUBTFUL ATTEMPT TO NOTIFY THE 35050000
- % REMOTE COMPUTER OF OUR FAILURE 35051000
- END 35052000
- ELSE % SENT PACKET OK--NOW GET ACKNOWLEDGMENT 35053000
- 35054000
- CASE PGET(TRUE) OF 35055000
- BEGIN 35056000
- % GOT A GOOD PACKET -- IS IT AN ACK? 35057000
- IF TYPE_CHAR=7"Y" THEN RETRY:=0 % SUCCESS !!! 35058000
- ELSE 35059000
- IF TYPE_CHAR=7"E" THEN % DISMAL FAILURE ON OTHER END 35060000
- BEGIN 35061000
- RETRY:= 0; 35062000
- PUTPACKET:= TRUE % PASS ON OUR FAILURE 35063000
- END 35064000
- ELSE TRYAGAIN; % TREAT ANYTHING ELSE AS A NAK 35065000
- 35066000
- % NOT A GOOD PACKET (IN VARIOUS FLAVORS): 35067000
- TRYAGAIN; % TIMEOUT 35068000
- ABORT; % EOF 35069000
- ABORT; % IO ERROR 35070000
- TRYAGAIN; % NOT A PACKET 35071000
- TRYAGAIN; % SHORT 35072000
- TRYAGAIN; % CHECKSUM ERROR 35073000
- RETRY:=0; % IT'S ON NEXT PACKET--ASSUME ACK MISSED35074000
- TRYAGAIN; % PRIOR PACKET NUMBER--MAY BE BAD NEWS 35075000
- TRYAGAIN % BAD PACKET NUMBER 35076000
- END CASE; 35077000
- END P U T P A C K E T ; 35078000
- PROCEDURE GETINIT; % EXTRACT INITIALIZATION VALUES FROM SEND-INIT 40000000
- % PACKET OR FROM ACK OF OUR SEND-INIT 40001000
- BEGIN 40002000
- REAL CHARNBR; 40003000
- POINTER PCH; % POINTER TO CURRENT CHAR 40004000
- 40005000
- % ESTABLISH DEFAULTS: 40006000
- YOURMAXBUFF:= MAXPACKET; 40007000
- YOURQUOTE:= 7"#"; 40008000
- YOUR8BIT:= 7"N"; 40009000
- 40010000
- % NOW GET THE SPECIFIC VALUES FROM OTHER KERMIT 40011000
- PCH:= FIRST_DATA; 40012000
- WHILE PKL> 0 AND CHARNBR < 11 DO 40013000
- BEGIN 40014000
- IF PCH NEQ 7" " THEN 40016000
- CASE CHARNBR OF 40017000
- BEGIN 40018000
- YOURMAXBUFF:= UNCHAR(PCH); % BUFSZ 40019000
- IF YOURTIMOUT:= UNCHAR(PCH) = MYTIMOUT THEN % TIMOUT40020000
- YOURTIMOUT:=*+ 1; % PREVENT CONTINUOUS COLLISIONS 40021000
- YOURNPAD:= UNCHAR(PCH); % NPAD 40022000
- YOURPAD:= CTL(ORD(PCH)); % PAD 40023000
- YOUREOL:= UNCHAR(PCH); % EOL 40024000
- YOURQUOTE:= ORD(PCH); % QUOTE 40025000
- YOUR8BIT:= ORD(PCH); % 8 BIT QUOTE 40026000
- ; % CHKTYPE 40027000
- YOURREPEAT:= ORD(PCH); % REPEAT QUOTE 40028000
- ;; % RESERVED 40029000
- END; 40030000
- PCH:=*+1; PKL:=*-1; 40030500
- CHARNBR:=*+ 1 40031000
- END; 40032000
- IF DEBUGGING THEN WRITE(DEBUGFILE,*/,YOURMAXBUFF, YOURTIMOUT 40033000
- ,YOURNPAD, YOURPAD 40034000
- ,YOUREOL, YOURQUOTE, YOUR8BIT 40035000
- ,YOURREPEAT 40036000
- ); 40037000
- 40038000
- % SET BIT IN CONTROL CHAR TRUTHSET FOR CONTROL QUOTE CHAR: 40039000
- CTLCHARS[YOURQUOTE.[7:3]].[(31-YOURQUOTE.[4:5]):1]:= 1; 40040000
- END G E T I N I T ; 40041000
- REAL PROCEDURE SETINIT; % RETURNS COUNT OF CHARACTERS SET IN BUILD 42000000
- BEGIN 42001000
- REPLACE FIRST_DATA BY KERCHAR(94) % BLKSZ 42002000
- ,KERCHAR(MYTIMOUT) % TIMOUT 42003000
- ,KERCHAR(MYPAD) % NPAD 42004000
- ,CTLCHAR(0) % PAD 42005000
- ,KERCHAR(ASCIICRVAL) % EOL 42006000
- ,7"#" % QUOTE 42007000
- ,7" " % NO 8 BIT QUOTING 42008000
- ,7"1" % CHKTYPE 42009000
- ,7" " % REPEAT-- NOT YET IMPLEMENTD42010000
- ; 42011000
- SETINIT:=9 42012000
- END S E T I N I T ; 42013000
- BOOLEAN PROCEDURE SEND_DATA (MRSZ); 60000000
- VALUE MRSZ; 60001000
- REAL MRSZ; % MAXRECSIZE 60002000
- BEGIN 60003000
- EBCDIC ARRAY FREC [0:MRSZ+1]; 60004000
- BOOLEAN RTN, DONE; % TEMP STORAGE FOR VALUE RETURNED, LOOP CONTROL 60005000
- REAL SZ, SZ2; 60006000
- POINTER P1,P2; 60007000
- REAL I,J; 60008000
- REAL FL,PL; % FILE AND PACKET CHARS LEFT 60009000
- POINTER FP,PP; % FILE AND PACKET POINTERS 60010000
- TRUTHSET NULLBLANK (48"00"" "); 60011000
- DEFINE 60012000
- YOURMAXDATA = YOURMAXBUFF - 5 # 60012500
- , RESETPKT = % START BUILDING A NEW DATA PACKET 60013000
- BEGIN 60014000
- PP:= FIRST_DATA; 60015000
- PL:= YOURMAXDATA 60016000
- END # 60017000
- , UNLOOP = 60018000
- BEGIN 60019000
- SEND_DATA:= DONE:= TRUE; 60020000
- FL:= -1; % GET OUT OF LOOP 60021000
- END # 60022000
- , SENDIT = 60023000
- IF PUTPACKET (DATA_TYPE,YOURMAXDATA-PL) THEN 60024000
- UNLOOP 60025000
- ELSE 60026000
- RESETPKT # 60027000
- , ERR(X) = 60028000
- BEGIN 60029000
- ERROUT(X); 60030000
- UNLOOP 60031000
- END # 60032000
- ; 60033000
- 60034000
- RESETPKT; % START A NEW DATA PACKET 60035000
- 60036000
- DO 60037000
- IF RTN:= READ(FYLE,MRSZ,FREC) THEN 60038000
- IF RTN.[9:1] THEN % EOF: 60039000
- BEGIN 60040000
- SENDIT; % SEND ANYTHING LEFT IN BUFFER 60041000
- DONE:= TRUE % AND EXIT LOOP 60042000
- END 60043000
- ELSE 60044000
- ERR (7"IO ERROR ENCOUNTERED IN READ OF FILE") 60045000
- ELSE 60046000
- BEGIN 60047000
- % REMOVE TRAILING BLANKS (AND NULLS FOLLOWING) 60048000
- P2:= FREC; SZ2:= MRSZ; 60049000
- DO % TRUNCATE TRAILING SPACES AND NULLS 60050000
- BEGIN 60051000
- SCAN P1:P2 FOR SZ:SZ2 UNTIL IN NULLBLANK; 60052000
- SCAN P2:P1 FOR SZ2:SZ WHILE = 8" "; 60053000
- SCAN P2:P2 FOR SZ2:SZ2 WHILE = 0; 60054000
- END 60055000
- UNTIL SZ2 = 0; 60056000
- 60057000
- % COUNT WHAT REMAINS, CONVERT IT TO ASCII 60058000
- % AND PLACE CRLF RECORD DELIMITER AT END 60059000
- REPLACE FREC BY FREC FOR FL:= MRSZ-SZ WITH EBCDICTOASCII 60060000
- , CHAR(ASCIICRVAL), CHAR(ASCIILFVAL); 60061000
- FL:= *+2; % ADD CR AND LF TO COUNT 60062000
- FP:= FREC; 60063000
- 60064000
- % QUOTE CONTROL CHARACTERS, DIVIDE UP INTO PACKETS AND 60065000
- % SEND OUT THE PACKETS: 60066000
- WHILE FL > 0 DO % DON'T NEED NEW READ OF INPUT FILE 60067000
- BEGIN 60068000
- I := MIN(FL,PL); 60069000
- REPLACE PP:PP BY FP:FP FOR J:I UNTIL IN CTLCHARS[0]; 60070000
- FL:=*- (I-J); 60071000
- PL:=*- (I-J); 60072000
- 60073000
- IF J > 0 THEN % POINTING TO CTL CHAR--QUOTE IT 60074000
- BEGIN 60075000
- IF PL=1 THEN SENDIT % NO ROOM FOR IT 60076000
- ELSE 60077000
- BEGIN 60078000
- IF FP=CHAR(YOURQUOTE) THEN 60079000
- % REPRESENT QUOTE CHAR BY QUOTE QUOTE: 60080000
- REPLACE PP:PP BY FP FOR 1, FP FOR 1 60081000
- ELSE 60082000
- REPLACE PP:PP BY CHAR(YOURQUOTE) 60083000
- , CTLCHAR(ORD(FP)); 60084000
- FP:=*+ 1; 60085000
- FL:=*- 1; 60086000
- PL:=*- 2; 60087000
- END END; 60088000
- 60089000
- IF PL = 0 THEN SENDIT % NEED TO SEND PACKET 60090000
- END END 60091000
- UNTIL DONE; 60092000
- END SEND_DATA; 60093000
- BOOLEAN PROCEDURE SEND_INIT; 65000000
- BEGIN 65001000
- REAL L,E; 65002000
- POINTER P1; 65003000
- BOOLEAN DONE; 65004000
- 65005000
- DEFINE ABORT = 65006000
- BEGIN 65007000
- SEND_INIT:= TRUE; 65008000
- E:= 0 65009000
- END # 65010000
- , SHUTDOWN = 65011000
- BEGIN 65012000
- ERROUT(7"IO ERROR"); 65013000
- ABORT 65014000
- END # 65015000
- , TRYAGAIN = # 65016000
- ; 65017000
- 65018000
- SEQ:= 0; 65019000
- 65020000
- DO % LOOP UNTIL SUCCESSFUL SEND AND ACK OR ABOSLUTE FAILURE 65021000
- BEGIN 65022000
- L:= SETINIT; 65023000
- IF PPUT(S_TYPE,L) THEN % IO ERROR 65024000
- SHUTDOWN 65025000
- ELSE % SENT S PACKET--NOW GET ACK 65026000
- CASE E:= PGET(TRUE) OF 65027000
- BEGIN 65028000
- IF TYPE_CHAR = 7"Y" THEN % GOT GOOD PKT--IS IT ACK? 65029000
- GETINIT % YES ACK, GET SPECS 65030000
- ELSE 65031000
- IF TYPE_CHAR = 7"E" THEN ABORT % ERROR ON OTHER END 65032000
- ELSE E:= 1; % ANYTHING ELSE SEEN AS NAK--TRY AGAIN 65033000
- 65034000
- TRYAGAIN; % TIMEOUT 65035000
- ABORT; % EOF 65036000
- SHUTDOWN; % IO ERROR 65037000
- TRYAGAIN; % NOT A PACKET 65038000
- TRYAGAIN; % SHORT PACKET 65039000
- TRYAGAIN; % CHECKSUM ERROR 65040000
- SEQ:=*+ 1; % BAD SEQ: ADAPT TO IT AND TRY AGAIN 65041000
- SEQ:=*- 1; % BAD SEQ: ADAPT TO IT AND TRY AGAIN 65042000
- SEQ:=*+ 1 % BAD SEQ: TRY TO ADAPT 65043000
- END END 65044000
- UNTIL E = 0 65045000
- END SEND_INIT; 65046000
- PROCEDURE SEND; 69000000
- BEGIN 69001000
- POINTER P1; 69002000
- 69003000
- YOUREOL:= ASCIICRVAL; % DEFAULT EOL CHAR 69004000
- 69005000
- IF BOOLEAN(FYLE.AVAILABLE) THEN 69006000
- IF NOT FYLE.ATTERR THEN % COMPATABLE ATTRIBUTES 69007000
- IF FYLE.BLOCKSTRUCTURE = VALUE(FIXED) THEN 69008000
- BEGIN 69009000
- WRITE(RMT,<4"07">); % DEL -- LET 'EM KNOW WE'RE UP 69010000
- WHEN(1); % ALLOW TIME FOR OTHER END TO GET READY 69010500
- 69010750
- IF SEND_INIT THEN % COULD NOT INITIATE COMMUNICATIONS 69011000
- ELSE 69012000
- BEGIN 69013000
- 69014000
- % SEND THE REMOTE FILE NAME BACK TO REMOTE SYSTEM 69015000
- SCAN P1:P(INIT) UNTIL = 0; 69016000
- REPLACE FIRST_DATA BY P(INIT) FOR OFFSET(P1)+1 69017000
- WITH EBCDICTOASCII; 69018000
- IF PUTPACKET (F_TYPE,OFFSET(P1)+1) THEN 69019000
- % FAILED SEND 69019500
- ELSE 69020000
- 69021000
- % SEND CONTENTS OF FILE 69022000
- IF SEND_DATA (IF FYLE.FRAMESIZE=48 THEN 69023000
- 6 * FYLE.MAXRECSIZE 69024000
- ELSE FYLE.MAXRECSIZE 69025000
- ) 69026000
- THEN % COULD NOT SEND ENTIRE FILE 69027000
- CLOSE(FYLE) 69028000
- ELSE 69029000
- BEGIN 69030000
- CLOSE(FYLE); 69031000
- IF PUTPACKET(Z_TYPE,0) THEN % SEND EOF 69032000
- ELSE PUTPACKET (B_TYPE,0) % BREAK--DONE 69033000
- END END END 69034000
- ELSE WRITE(RMT,<"FILE STRUCTURE IS NOT READABLE BY KERMIT" 69035000
- 4"3D">) 69035500
- ELSE % SYSTEM SHOULD HAVE SENT FILE ATTR ERR MSG 69036000
- ELSE WRITE(RMT,<8"THE FILE YOU REQUESTED IS NOT AVAILABLE"4"3D">) 69037000
- END SEND; 69038000
- BOOLEAN PROCEDURE RCV_DATA(MINREC,MAXREC); 70000000
- VALUE MINREC,MAXREC; 70001000
- REAL MINREC,MAXREC; 70002000
- BEGIN 70003000
- REAL T,LI,L2,LO; % PACKET TYPE, CHARACTER COUNTS 70004000
- POINTER PI,PO; % INPUT AND OUTPUT POINTERS 70005000
- EBCDIC ARRAY OUTBUFF[0:MAXREC-1]; 70006000
- DEFINE CR=47"0D"#, LF=47"0A"#; 70007000
- TRUTHSET NEWLINE (CR OR LF); 70008000
- 70009000
- DEFINE FORWARD(X)= 70010000
- BEGIN 70011000
- PI:=*+(X); 70012000
- LI:=*-(X) 70013000
- END # 70014000
- , CLEAROUTBUFF = 70015000
- BEGIN 70016000
- LO:= 0; % NO CHARS IN BUFFER 70017000
- REPLACE PO:= OUTBUFF BY 8" " FOR MAXREC 70018000
- END # 70019000
- ; 70020000
- 70021000
- $SET OMIT= NDLSETUP 70021250
- DEFINE INITAUTO= PPUT(ACK_TYPE,0) #; % NDL DOES NOT SUPPORT AUTO RCV70021500
- $POP OMIT SET OMIT= NOT NDLSETUP 70021750
- BOOLEAN PROCEDURE INITAUTO; % NDL SUPPORTS AUTO RECV 70022000
- % % INITIATE NDL AUTOMATIC DATA PACKET RECEIVE 70023000
- BEGIN 70024000
- REPLACE PKT BY AUTORCV, KERCHAR(YOURNPAD),KERCHAR(YOURPAD) 70025000
- , KERCHAR(0), KERCHAR(SEQ.[5:6]),8"D"; 70026000
- INITAUTO:= WRITE(RMT[STOP],6,PKT); 70027000
- DEBUGARRAY (6,PKT,8"AUTINT",TRUE); 70028000
- END; 70029000
- $POP OMIT 70029500
- BOOLEAN PROCEDURE REINIT; % NDL DROPPED OUT OF AUTO RECEIVE 70030000
- BEGIN 70031000
- IF NOT INITAUTO THEN % SENT INIT TO NDL OK 70032000
- BEGIN 70033000
- REPLACE COUNT_CHAR BY FIRST_DATA FOR PKL; % LIKE AN AUTOPKT70034000
- REINIT:= TRUE; % TRUE RESULT INDICATES SUCCESS 70035000
- END 70036000
- END REINIT; 70037000
- 70038000
- % RCV_DATA STATEMENTS: 70039000
- CLEAROUTBUFF; % PREPARE OUTPUT BUFFER AND POINTER 70040000
- 70041000
- % PUT NDL INTO AUTO RECEIVE MODE: 70042000
- IF INITAUTO THEN % FAILED 70043000
- RCV_DATA:= TRUE % REPORT FAILURE TO RECEIVE FILE 70044000
- ELSE 70045000
- 70046000
- %LOOP FOR EVERY DATA PACKET 70047000
- WHILE 70048000
- IF LO > MAXREC THEN FALSE % ABORT EXIT 70049000
- ELSE 70050000
- IF BOOLEAN(T:= GETPACKET(FALSE)) THEN 70051000
- FALSE % NOT DATA PACKET 70051500
- ELSE % DATA PACKET--AUTO OR OTHERWISE 70052000
- IF T = DATA_TYPE THEN 70053000
- REINIT % GOOD PACKET--BUT ALSO RESTART NDL AUTO70054000
- ELSE TRUE % GOOD AUTO PACKET--CONTINUE LOOPING 70055000
- DO 70056000
- BEGIN 70057000
- PI:= COUNT_CHAR; % DATA PART OF PACKET STARTS HERE 70057250
- LI:= PKL; % LENGTH OF DATA IN PACKET 70057500
- 70057750
- % BREAK INTO LOGICAL RECORDS: 70058000
- DO 70059000
- BEGIN 70060000
- SCAN PI FOR L2:LI UNTIL IN NEWLINE; 70061000
- L2:= LI-L2; % # CHARS TO END OF LINE 70062000
- LI:= *-L2; % # CHARS LEFT IN INPUT AFTER THIS LINE 70063000
- IF LO:=*+L2 > MAXREC THEN % RECORD TOO LARGE 70064000
- BEGIN 70065000
- LI:=0; % SIMULATE END OF PACKET TO EXIT LOOP 70066000
- ERROUT(7"RECORD TOO LONG TO FIT INTO FILE"); 70067000
- RCV_DATA:= TRUE; % REPORT FAILURE TO CALLER 70068000
- END 70069000
- ELSE 70070000
- BEGIN 70071000
- REPLACE PO:PO BY PI:PI FOR L2 WITH ASCIITOEBCDIC; 70072000
- IF LI > 0 THEN % STILL DATA CHARS IN PKT 70072500
- IF PI IN NEWLINE THEN % END OF A RECORD 70073000
- BEGIN 70074000
- IF PI=CR THEN 70075000
- IF CAND (LI>1, PI+1=LF) THEN 70075500
- FORWARD(2) % CRLF 70076000
- ELSE FORWARD(1) % CR 70077000
- ELSE FORWARD(1); % LF 70078000
- WRITE (FYLE,MAX(MINREC,LO),OUTBUFF); 70079000
- 70080000
- CLEAROUTBUFF 70081000
- END END END 70082000
- UNTIL LI=0 % LOOP UNTIL END OF INPUT REC 70083000
- END; % LOOP UNTIL ALL PACKETS HAVE BEEN RECEIVED 70084000
- 70085000
- % CLOSE FILE...IF SUCCESSFULLY RECEIVED ENTIRE FILE THE FILE 70086000
- % IS CLOSED WITH LOCK, OTHERWISE JUST RELEASED 70087000
- IF T = Z_TYPE THEN % GOT EOF PACKET 70088000
- LOCK(FYLE,CRUNCH) 70089000
- ELSE 70089250
- BEGIN 70089500
- CLOSE(FYLE); 70090000
- RCV_DATA:= T= ERR_TYPE % DO NOT WAIT FOR BREAK IF ERROR 70090250
- END 70090500
- END RCV_DATA; 70091000
- BOOLEAN PROCEDURE RCV_INIT; 75000000
- BEGIN 75001000
- REAL E; % ERROR CODE FROM PGET 75002000
- DEFINE TRYAGAIN = % E IS ALREADY NON-ZERO SO CONTINUE LOOP75003000
- BEGIN 75004000
- IF PPUT (NAK_TYPE,0) THEN ABORT 75005000
- END # 75006000
- , ABORT = 75007000
- BEGIN 75008000
- RCV_INIT:= TRUE; % NOTIFY CALLER OF FAILURE 75009000
- E:= 0 % GET OUT OF LOOP 75010000
- END # 75011000
- , SHUTDOWN = 75012000
- BEGIN 75013000
- ERROUT(7"IO ERROR"); % TRY TO TELL REMOTE 75014000
- ABORT % NOW GO AWAY 75015000
- END # 75016000
- , SYNC_SEQ = % GOT AN UNEXPECTED SEQ VALUE 75017000
- BEGIN 75018000
- SEQ:= ORD(SEQ_CHAR); % CHANGE OUR EXPECTATION 75019000
- TRYAGAIN 75020000
- END # 75021000
- ; 75022000
- 75023000
- DO % LOOP UNTIL AN S-PACKET IS RECEIVED 75024000
- CASE E:= PGET(TRUE) OF 75025000
- BEGIN 75026000
- % A GOOD PACKET-- IS IT AN "S" PACKET? 75027000
- IF TYPE_CHAR = 7"S" THEN 75028000
- BEGIN 75029000
- GETINIT; % EXTRACT S PACKET PARAMETERS 75030000
- E:= SETINIT; % SET UP ACK PACKET PARAMETERS 75031000
- IF PPUT(ACK_TYPE,E) THEN % AND SEND ACK 75032000
- ABORT % FATAL IO ERROR 75033000
- ELSE E:= 0 % SUCCESS -- GET OUT OF LOOP 75034000
- END 75035000
- ELSE 75036000
- IF TYPE_CHAR = 7"E" THEN 75037000
- ABORT % INDICATE FATAL ERROR--EXIT LOOP 75038000
- ELSE % TREAT ANY OTHER PACKET AS A NAK 75039000
- E:= 1; % AND LOOP BACK FOR MORE 75040000
- 75041000
- % NO PACKET RECEIVED: 75042000
- TRYAGAIN; % TIMEOUT 75043000
- ABORT; % EOF 75044000
- SHUTDOWN; % IO ERROR 75045000
- TRYAGAIN; % NOT A PACKET 75046000
- TRYAGAIN; % SHORT PACKET 75047000
- TRYAGAIN; % CHECKSUM ERROR 75048000
- SYNC_SEQ; % 75049000
- SYNC_SEQ; % OUT OF SEQUENCE--RESET SEQ AND RETRY 75050000
- SYNC_SEQ; % 75051000
- END CASE 75052000
- UNTIL E=0 75053000
- END RCV_INIT; 75054000
- PROCEDURE RECV; 79000000
- BEGIN 79001000
- % IF CAND(NOT FYLE.NEWFILE, FYLE.RESIDENT) THEN 79002000
- % WRITE(RMT,<8"A FILE ALREADY EXISTS WITH THE SAME NAME AS " 79004000
- % 8"THE FILE YOU WISHED TO CREATE" 4"3D">) 79005000
- % ELSE 79006000
- IF COR(FYLE.BLOCKSTRUCTURE=VALUE(FIXED) 79007000
- ,FYLE.BLOCKSTRUCTURE=VALUE(EXTERNAL) AND 79008000
- FYLE.KIND=VALUE(REMOTE) OR FYLE.KIND=VALUE(PRINTER) 79009000
- OR FYLE.KIND=VALUE(TAPE) 79010000
- ) 79011000
- THEN % ACCEPTABLE BLOCK STRUCTURE 79012000
- BEGIN 79013000
- FYLE.OPEN:= TRUE; 79014000
- WHEN(1); % ACCOMODATE POKEY APPLE 79014500
- IF FYLE.ATTERR THEN % TELL OTHER END WE'VE FAILED 79015000
- WRITE(RMT,<4"3D">) % BY SENDING A NAK 79016000
- ELSE 79017000
- BEGIN 79018000
- WRITE(RMT,<4"07">); % DEL TO LET 'EM KNOW WE'RE READY 79019000
- IF RCV_INIT THEN % UNABLE TO ESTABLISH 79020000
- ELSE % KERMIT TALKING TO KERMIT OK 79021000
- % GET AND IGNORE FILE ID PACKET 79022000
- IF GETPACKET(TRUE) = F_TYPE THEN 79023000
- BEGIN 79024000
- 79024250
- % ACTUAL FILE TRANSFER: 79024500
- IF NOT RCV_DATA 79025000
- (IF FYLE.MINRECSIZE=0 THEN 79025050
- FYLE.MAXRECSIZE 79025100
- ELSE FYLE.MINRECSIZE 79025150
- ,FYLE.MAXRECSIZE 79025200
- ) 79025250
- THEN 79025500
- IF GETPACKET(TRUE) NEQ B_TYPE THEN 79026000
- ERROUT(7"CAN ONLY RECEIVE ONE FILE") 79027000
- END END END 79028000
- ELSE WRITE(RMT,<8"ILLEGAL BLOCKSTRUCTURE"4"3D">) 79029000
- END R E C V ; 79030000
- % OUTER BLOCK STATEMENTS START HERE: 90000000
- 90002000
- REPLACE P(CTLCHARS,0) BY 4"0000FFFFFFFF" FOR 1 WORDS, 0 FOR 2 WORDS 90003000
- , 4"000000000001" FOR 1 WORDS 90004000
- , P(CTLCHARS,0) FOR 4 WORDS 90005000
- ; % SET UP DYNAMIC TRUTHSET--LATER ADD CTL QUOTE90006000
- YOURTIMOUT:= MYTIMOUT+1; % THE TWO TIMEOUTS SHOULD BE DIFFERENT 90007000
- MARK:=1; % MARK DEFAULTS TO ASCII SOH CHARACTER 90008000
- DEBUGGING:= BOOLEAN(MYSELF.TASKVALUE); 90009000
- 90011000
- IF FYLE.MYUSE = VALUE(IN) THEN SEND 90012000
- ELSE RECV 90013000
- END. 99999999
-